package datapack

import (
	"broker/interface/idatapack"
	"broker/interface/imodel"
	"broker/struct/model"
	"broker/utils"
	"encoding/binary"
	"errors"
)

/**
 * @Description
 * @Author huan.wang
 * @Date 2021/4/24 10:11 下午
 **/

type ConnectDataPack struct {
}

func NewConnectDataPack() idatapack.IDataPack {
	return &ConnectDataPack{}
}

func (c ConnectDataPack) Pack(message imodel.IMessage) ([]byte, error) {
	panic("no implement")
}

func (c ConnectDataPack) UnPack(bytes []byte) (imodel.IMessage, error) {
	pdp := NewParamDataPack(bytes)
	paramData, err := pdp.UnPack()
	if err != nil {
		return nil, errors.New("协议类型读取错误")
	}
	if string(paramData.GetData()) != "MQTT" {
		return nil, errors.New("协议类型错误")
	}
	paramData, err = pdp.UnPackByLen(1)
	if err != nil {
		return nil, errors.New("协议版本错误")
	}
	var protocol byte
	binary.Read(paramData.GetDataBuffer(), binary.BigEndian, &protocol)
	if protocol != 4 {
		return nil, errors.New("协议版本不支持")
	}
	var connFlag byte
	paramData, err = pdp.UnPackByLen(1)
	if err != nil {
		return nil, errors.New("连接标志读取错误")
	}
	connMsg := model.NewConnectMessage()
	binary.Read(paramData.GetDataBuffer(), binary.BigEndian, &connFlag)
	connMsg.UserNameFlag = utils.GetBinaryBit(connFlag, 0)
	connMsg.PassWordFlag = utils.GetBinaryBit(connFlag, 1)
	connMsg.WillRetain = utils.GetBinaryBit(connFlag, 2)
	connMsg.WillQos = utils.GetBinaryBit(connFlag, 3)<<1 | utils.GetBinaryBit(connFlag, 4)
	connMsg.WillFlag = utils.GetBinaryBit(connFlag, 5)
	connMsg.CleanSession = utils.GetBinaryBit(connFlag, 6)

	var keepAlive uint16
	paramData, err = pdp.UnPackByLen(2)
	if err != nil {
		return nil, errors.New("保活时间读取错误")
	}
	binary.Read(paramData.GetDataBuffer(), binary.BigEndian, &keepAlive)
	connMsg.KeepAlive = uint32(keepAlive)
	paramData, err = pdp.UnPack()
	if err != nil {
		return nil, errors.New("客户端标识符读取错误")
	}
	connMsg.ClientID = string(paramData.GetData())
	if connMsg.WillFlag == 1 {
		//读取遗嘱主题
		paramData, err = pdp.UnPack()
		if err != nil {
			return nil, errors.New("遗嘱主题读取错误")
		}
		connMsg.WillTopic = string(paramData.GetData())
		//读取遗嘱消息
		paramData, err = pdp.UnPack()
		if err != nil {
			return nil, errors.New("遗嘱消息读取错误")
		}
		connMsg.WillMsg = string(paramData.GetData())
	}

	if connMsg.UserNameFlag == 1 {
		paramData, err = pdp.UnPack()
		if err != nil {
			return nil, errors.New("用户名读取错误")
		}
		connMsg.UserName = string(paramData.GetData())
	}
	if utils.GetBinaryBit(connFlag, 1) == 1 {
		paramData, err = pdp.UnPack()
		if err != nil {
			return nil, errors.New("密码读取错误")
		}
		connMsg.PassWord = string(paramData.GetData())
	}
	return connMsg, nil
}
